﻿#include "videowall.h"
#include <QDebug>

using namespace QtAV;

VideoWall::VideoWall(QWidget *parent)
    : QWidget(parent)
{
    videoLocation=QStandardPaths::writableLocation(QStandardPaths::MoviesLocation);

    this->showFullScreen();
    this->testAttribute(Qt::WA_OpaquePaintEvent);

    clock = new AVClock(this);
    clock->setClockType(AVClock::ExternalClock);

    initializeWall();
    createMenu();
}

VideoWall::~VideoWall()
{
    if(!players.isEmpty())
    {
        foreach (AVPlayer *player, players) {
            player->stop();
            VideoRenderer* renderer = player->renderer();
            if (renderer->widget()) {
                renderer->widget()->close();
                if (!renderer->widget()->testAttribute(Qt::WA_DeleteOnClose) && !renderer->widget()->parent())
                    delete renderer;
                delete player;
            }
        }
        players.clear();
    }
}

void VideoWall::initializeWall()
{
    QGridLayout *layout = new QGridLayout;
    layout->setSizeConstraint(QLayout::SetMaximumSize);
    layout->setSpacing(1);
    layout->setMargin(0);
    layout->setContentsMargins(0, 0, 0, 0);
    this->setLayout(layout);

    VideoRendererId vid=VideoRendererId_Direct2D;

    QRect rect=qApp->desktop()->screenGeometry();
    cols=qRound(qreal(rect.width() / WIDTH_MIN));
    rows=qRound(qreal(rect.height() / HEIGHT_MIN));

    for(int r=0; r < rows; r++)
    {
        for(int c=0;c < cols ; c++)
        {
            QtAV::VideoRenderer *renderer=QtAV::VideoRenderer::create(vid);
            renderer->widget()->setWindowFlags(renderer->widget()->windowFlags()| Qt::FramelessWindowHint);
            renderer->widget()->setAttribute(Qt::WA_DeleteOnClose);
            layout->addWidget(renderer->widget(),r,c);

            AVPlayer *player = new AVPlayer;
            player->setRenderer(renderer);
            player->masterClock()->setClockAuto(false);
            player->masterClock()->setClockType(AVClock::ExternalClock);
            players.append(player);
        }
    }
}

void VideoWall::play(const QString &file)
{
    if (players.isEmpty())
        return;

    clock->start();

    foreach (AVPlayer *player, players) {
        player->play(file);
    }
    timer_id=startTimer(INTERVAL);
}

void VideoWall::detectState()
{
    if(players.isEmpty())
        return;

    foreach (AVPlayer* player, players) {
        if (!player->isPlaying()) {
            player->play();
            return;
        }
        player->pause(!player->isPaused());
    }
}

void VideoWall::stop()
{
    if(players.isEmpty())
        return;

    clock->reset();
    killTimer(timer_id);
    foreach (AVPlayer* player, players) {
        player->stop();
    }
}

void VideoWall::open()
{
    QString file = QFileDialog::getOpenFileName(this, QStringLiteral("选择媒体文件"),videoLocation);
    if (file.isEmpty())
        return;

    this->stop();
    this->play(file);
}

void VideoWall::contextMenuEvent(QContextMenuEvent *)
{
    menu->exec(QCursor::pos());
}

void VideoWall::timerEvent(QTimerEvent *event)
{
    if(event->timerId() == timer_id)
    {
        foreach (AVPlayer *player, players) {
            player->masterClock()->updateExternalClock(*clock);
        }
    }
}

void VideoWall::keyPressEvent(QKeyEvent *event)
{
    if(event->modifiers() == Qt::ControlModifier && event->key()==Qt::Key_O)
        open();
    else if(event->modifiers() == Qt::ControlModifier && event->key()==Qt::Key_Q)
        this->close();
    else
    {
        switch (event->key()) {
        case Qt::Key_Space:
            detectState();
            break;
        case Qt::Key_Escape:
            if(players.first()->isPlaying() || players.first()->isPaused())
                stop();
            else
                close();
            break;
        }
    }
}

void VideoWall::createMenu()
{
    menu=new QMenu(this);
    menu->addAction(QStringLiteral("打开 (Ctrl+O)..."),this,&VideoWall::open);
    menu->addSeparator();
    menu->addAction(QStringLiteral("暂停/恢复"),this,&VideoWall::detectState);
    menu->addAction(QStringLiteral("结束"),this,&VideoWall::stop);
    menu->addSeparator();
    menu->addAction(QStringLiteral("退出 (Ctrl+Q)"),this,&QWidget::close);
}
